import socketserver
import struct
import pickle
import threading
import os
import json
from posts import post1,post2,post3,post4,post5



USERS_FILE = "users.json"
USAGE_FILE = 'user_usage_data.json'

def load_users():
    if os.path.exists(USERS_FILE):
        with open(USERS_FILE, "r") as f:
            return json.load(f)
    return {}

def save_users(users):
    with open(USERS_FILE, "w") as f:
        json.dump(users, f, indent=2)
class DataStorage:

    def __init__(self, filepath: str):
        self.filepath = filepath
        self.today = '4.30'
        self.user_data = {}
        self._load_data()


    def _load_data(self):
        with open(self.filepath, 'r') as f:
            raw = json.load(f)

        for user, entries in raw.items():
            if not isinstance(entries, list) or len(entries) < 2:
                continue
            user_id = entries[0] if isinstance(entries[0], str) else None
            daily_entries = entries[1:]
            parsed_days = []

            for item in daily_entries:
                if not (isinstance(item, list) and len(item) == 2):
                    continue
                date, usage = item

                if date == self.today:
                    # detailed record for today
                    record = {
                        'date':      date,
                        'TikTok':    round(usage.get('TikTok', 0), 1),
                        'Youtube':   round(usage.get('Youtube', 0), 1),
                        'Instagram': round(usage.get('Instagram', 0), 1),
                        'Total':     round(usage.get('Total', 0), 1),
                    }
                else:
                    # simplified record for past days
                    video_time = (
                        usage.get('TikTok', 0) +
                        usage.get('Youtube', 0) +
                        usage.get('Instagram', 0)
                    )
                    record = {
                        'date':      date,
                        'videotime': round(video_time, 1),
                        'totaltime': round(usage.get('Total', 0), 1),
                    }

                parsed_days.append((date, record))

            self.user_data[user] = {
                'id':    user_id,
                'daily': parsed_days,

            }


    def get_user_data(self):
        return self.user_data

    def get_today_data(self):
        return self.user_data.get(self.today, [])
class RequestHandler(socketserver.StreamRequestHandler):
    UsersLock = threading.Lock()
    trades = []
    posts = [post1,post2,post3,post4,post5]
    users = load_users()
    tokens = {}
    connected_clients = []
    print(users)
    data_storage = DataStorage("user_usage_data.json")
    Call = dict(
        REGISTER=(lambda self, *args: self.register(*args)),
        LOGIN=(lambda self, *args: self.login(*args)),
        DELETE=(lambda self, *args: self.delete(*args)),
        GET_USER_DATA=(lambda self, *args: self.data_storage.get_user_data()),
        GET_TODAY_DATA=(lambda self, *args: self.data_storage.get_today_data()),
        CREATE_TRADE=(lambda self, *args: self.create_trade(*args)),
        GET_TRADES=(lambda self, *args: self.get_trades()),
        CREATE_POST=(lambda self, *args: self.create_post(*args)),
        GET_POSTS = (lambda self, *args: self.get_posts()),
        GET_TOKEN = (lambda self, *args: self.get_token(*args)),
        SET_TOKEN = (lambda self, *args: self.set_token(*args)),
    )

    def handle(self):
        SizeStruct = struct.Struct("!I")
        size_data = b''
        while len(size_data) < SizeStruct.size:
            more = self.rfile.read(SizeStruct.size - len(size_data))
            if not more:
                return  # 连接关闭
            size_data += more
        size = SizeStruct.unpack(size_data)[0]

        data_bytes = b''
        while len(data_bytes) < size:
            more = self.rfile.read(size - len(data_bytes))
            if not more:
                return  # 连接关闭
            data_bytes += more

        data = pickle.loads(data_bytes)
        command = data[0]
        args = data[1:]

        try:
            with RequestHandler.UsersLock:
                function = RequestHandler.Call.get(command)
            if function is None:
                reply = (False, "Invalid command")
            else:
                reply = function(self, *args)
        except Exception as e:
            reply = (False, f"Server error: {str(e)}")

        reply_data = pickle.dumps(reply, protocol=3)
        self.wfile.write(SizeStruct.pack(len(reply_data)))
        self.wfile.write(reply_data)

    def login(self,username,password):
        # SizeStruct = struct.Struct("!I")
        with RequestHandler.UsersLock:
            if username in self.users:
                return False, "Username already exists"
            else:
                self.users[username] = password
                save_users(self.users)
                # data = {
                #     'username': username,
                #     'password': password,
                # }
                # reply_data = pickle.dumps(data, 3)
                # self.wfile.write(SizeStruct.pack(len(reply_data)))
                # self.wfile.write(reply_data
            return True, "User registered"

    def create_trade(self,data):
        with RequestHandler.UsersLock:
            if data['seller'] in self.users:
                self.trades.append(data)
                return True, "Trade created"
        return False,"Seller does not exist"

    def get_trades(self):
        with RequestHandler.UsersLock:
            return self.trades.copy()  # 避免外部修改原数据

    def create_post(self,data):
        with RequestHandler.UsersLock:
            if data['username'] in self.users and data['password'] == self.users[data['username']]:
                self.posts.append(data)
                return True, "Post created"
        return False,"user does not exist"

    def get_posts(self):
        with RequestHandler.UsersLock:
            return self.posts.copy()

    def set_token(self,data):
        with RequestHandler.UsersLock:
            if data['username'] in self.tokens:
                self.tokens[data['username']] = data['token']
                return True, "token set"
        return False,"user does not exist"
    def get_token(self,username):
        with RequestHandler.UsersLock:
            if username in self.users:
                return self.tokens[username]
        return False,"user does not exist"
class UserServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass



if __name__ == "__main__":
    HOST, PORT = "0.0.0.0", 9999
    with UserServer((HOST, PORT), RequestHandler) as server:  # type: ignore
        print(f"User server running on {HOST}:{PORT}")
        server.serve_forever()
